#include <vector>
#include <iostream>
using namespace std;

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int step = nums[0];
        // 处理边界情况：如果数组只有一个元素
        // 那么我们已经在终点，无论这个元素的值是多少（只要非负，题目中 nums[i] 确实是非负的）
        // 都可以认为是成功的
        if(nums.size() == 1 && nums[0] >= 0)
            return true;
        int size = nums.size();
        for(int i = 1; i < size; i++)
        {
            // 在尝试跳到当前位置后，检查剩余的步数是否为0
            // 如果为0，说明我们无法再向前移动，因此返回false
            if(step == 0)
                return false;  

            // 每向前移动一个位置，我们消耗掉一步，所以剩余步数减1
            step--;

            // 这是贪心算法的核心步骤
            // 比较当前剩余的步数和当前位置能够提供的最大跳跃步数
            // 如果当前位置能跳得更远（nums[i]更大），我们就更新剩余步数为nums[i]
            // 这代表我们选择了当前最优的跳跃策略，以达到尽可能远的位置
            if(step < nums[i])
                step = nums[i];

            // 检查当前位置加上剩余的最大步数是否能够到达或超过数组的最后一个位置
            // 如果可以，说明我们能够成功跳到终点，直接返回true
            if(step + i >= size - 1)
                return true; 

            // 再次检查步数是否为0（虽然上面刚减过，但经过step = nums[i]后可能变为0）
            // 如果为0，说明在当前位置无法再向前移动，返回false
            if(step == 0)
                return false;  
        }
        
        // 如果循环正常结束（遍历了所有元素仍未返回）
        // 这意味着我们到达了数组的最后一个元素，因此返回true
        // 然而，在实际执行中，如果能到达最后一个元素，通常在循环内部就会触发 step + i >= size - 1 的判断
        return true;   
    }
};

